package io.renren.modules.workmanagement.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.workmanagement.constans.UserConstans;
import io.renren.modules.workmanagement.dao.ClassDao;
import io.renren.modules.workmanagement.entity.ClassEntity;
import io.renren.modules.workmanagement.entity.DepartmentEntity;
import io.renren.modules.workmanagement.entity.StudentEntity;
import io.renren.modules.workmanagement.service.ClassService;
import io.renren.modules.workmanagement.service.DepartmentService;
import io.renren.modules.workmanagement.service.StudentService;
import io.renren.modules.workmanagement.utils.PojoUtils;
import io.renren.modules.workmanagement.vo.ClassVO;
import io.renren.modules.workmanagement.vo.StudentVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service("classService")
public class ClassServiceImpl extends ServiceImpl<ClassDao, ClassEntity> implements ClassService {
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private SysUserService sysUserService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key = (String) params.get("key");
        LambdaQueryWrapper<ClassEntity> wrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(key)){
            wrapper.like(ClassEntity::getName, "%"+key+"%");
        }
        Long userId = (Long) params.get(UserConstans.USER_ID_KEY);
        //获取该用户所在的系部
        DepartmentEntity department = departmentService.getByAdminId(userId);
        IPage<ClassEntity> page = this.page(
                new Query<ClassEntity>().getPage(params),
                wrapper.eq(ClassEntity::getDepartmentId, department.getId()).orderByAsc(ClassEntity::getName)
        );
        List<ClassEntity> records = page.getRecords();
        List<Long> classIds = PojoUtils.streamMapList(records, ClassEntity::getId);
        List<StudentEntity> studentEntityList = studentService.getListByClassIds(classIds);
        Map<Long, List<StudentVO>> collect = null;
        if (CollectionUtil.isNotEmpty(studentEntityList)) {
            Map<Long, StudentEntity> studentMap = PojoUtils.listToMap(studentEntityList, StudentEntity::getUserId, Function.identity());
            List<SysUserEntity> sysUserList = sysUserService.getByIds(studentMap.keySet());
            collect = sysUserList.stream().map(sysUser -> {
                StudentEntity studentEntity = studentMap.get(sysUser.getUserId());
                StudentVO studentVO = new StudentVO();
                studentVO.setId(sysUser.getUserId());
                studentVO.setStuNo(Long.parseLong(sysUser.getUsername()));
                studentVO.setStuName(sysUser.getName());
                studentVO.setMobili(sysUser.getMobile());
                studentVO.setEmail(sysUser.getEmail());
                studentVO.setStatus(sysUser.getStatus());
                studentVO.setClassId(studentEntity.getClassId());
                return studentVO;
            }).collect(Collectors.groupingBy(StudentVO::getClassId));
        }
        Map<Long, List<StudentVO>> finalCollect = collect;
        IPage<ClassVO> convert = page.convert(item -> {
            ClassVO classVO = new ClassVO();
            if(finalCollect != null){
            List<StudentVO> studentVOS = finalCollect.get(item.getId());
            if(CollectionUtil.isNotEmpty(studentVOS)){
                classVO.setStudents(studentVOS);
                classVO.setStudentCount(studentVOS.size());
            }else {
                classVO.setStudents(new ArrayList<>());
                classVO.setStudentCount(0);
            }

            }
            BeanUtils.copyProperties(item, classVO);
            classVO.setDepartmentName(department.getName());
            return classVO;
        });
        return new PageUtils(convert);
    }

    @Override
    public ClassVO getClassById(Long id) {
        //获取班级信息
        ClassEntity classEntity = this.getById(id);
        ClassVO classVO = new ClassVO();
        BeanUtils.copyProperties(classEntity, classVO);
        DepartmentEntity departmentEntity = departmentService.getById(classEntity.getDepartmentId());
        classVO.setDepartmentName(departmentEntity.getName());
        return classVO;
    }

    @Override
    public void saveClass(ClassEntity classEntity, Long userId) {
        //获取管理员所在的部门
        DepartmentEntity departmentEntity = departmentService.getByAdminId(userId);
        classEntity.setDepartmentId(departmentEntity.getId());
        try {
            this.save(classEntity);
        } catch (Exception e) {
            throw new RRException("该班级已经存在");
        }
    }

    @Override
    public List<ClassEntity> getByDepartmentId(Long id) {
        return this.list(new LambdaQueryWrapper<ClassEntity>().eq(ClassEntity::getDepartmentId, id));
    }

    @Override
    public void changeStuStatus(Long stuNo, Integer status) {
        SysUserEntity sysUserEntity = sysUserService.getByUsername(stuNo);
        sysUserEntity.setStatus(status);
        sysUserService.update(sysUserEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByIdsExt(List<Integer> asList) {
        this.removeByIds(asList);
        //删除班级下的学生
        studentService.removeByClassIds(asList);
    }

    @Override
    public List<ClassEntity> likeByName(String key) {
        return this.lambdaQuery().like(ClassEntity::getName, "%" + key + "%").list();
    }
}
